# MainGame.gd
extends Node2D

@onready var player: Player = $Player
@onready var hud: CanvasLayer = $HUD # Reference to the HUD scene instance
@onready var upgrade_screen: CanvasLayer = $UpgradeScreen # Reference to UpgradeScreen instance
@onready var game_over_screen: CanvasLayer = $GameOverScreen # Reference to GameOverScreen instance

@onready var enemy_container: Node2D = $EnemyContainer
@onready var projectile_container: Node2D = $ProjectileContainer
@onready var orb_container: Node2D = $OrbContainer
@onready var enemy_spawn_timer: Timer = $EnemySpawnTimer

# Level Management
var current_level_node: Node = null

# Spawner Config
@export var initial_spawn_interval: float = 2.0
@export var min_spawn_interval: float = 0.2
@export var spawn_interval_decrease_rate: float = 0.01 # Per second

var current_spawn_interval: float = 2.0

# Enemy Prefabs - Load dynamically based on level or use resources
# Example direct loading (replace with level-specific logic):
@export var basic_enemy_scenes: Array[PackedScene] = [
	preload("res://scenes/enemies/common/Slime.tscn"),
	#preload("res://scenes/enemies/common/Bat.tscn"),
	# Add more basic enemy scenes here
]

func _ready():
	
	# Start game logic via GameManager
	GameManager.start_game()

	# Ensure containers exist for group lookups
	enemy_container.add_to_group("enemy_container")
	projectile_container.add_to_group("projectile_container")
	orb_container.add_to_group("orb_container")

	current_spawn_interval = initial_spawn_interval
	enemy_spawn_timer.wait_time = current_spawn_interval
	enemy_spawn_timer.timeout.connect(_on_enemy_spawn_timer_timeout)
	enemy_spawn_timer.start()

	# Load the first level immediately
	load_level(GameManager.level_order[0])
	print("MainGame Scene Ready")


func _process(delta):
	# Update spawner difficulty over time
	if not GameManager.is_paused and not GameManager.is_game_over:
		current_spawn_interval = max(min_spawn_interval, current_spawn_interval - spawn_interval_decrease_rate * delta)
		enemy_spawn_timer.wait_time = current_spawn_interval


func _on_enemy_spawn_timer_timeout():
	if GameManager.is_game_over or GameManager.is_paused: return
	if not is_instance_valid(player): return

	spawn_enemy()


func spawn_enemy():
	# TODO: Implement level-specific spawning, elite/boss spawning based on time/kills
	if basic_enemy_scenes.is_empty():
		printerr("No enemy scenes defined for spawning!")
		return

	# Choose a random basic enemy for now
	var enemy_scene = basic_enemy_scenes.pick_random()
	if not enemy_scene:
		printerr("Invalid enemy scene picked")
		return

	var enemy_instance = enemy_scene.instantiate()
	if not enemy_instance:
		printerr("Failed to instantiate enemy scene")
		return

	# Find a spawn position outside the screen view
	var spawn_position = find_spawn_position()
	enemy_instance.global_position = spawn_position

	# TODO: Apply difficulty scaling (increase health/damage based on GameManager.get_level_time_modifier())
	# if enemy_instance.has_method("scale_difficulty"):
	# 	enemy_instance.scale_difficulty(GameManager.get_level_time_modifier())

	enemy_container.add_child(enemy_instance)
	# print("Spawned enemy at", spawn_position)


func find_spawn_position() -> Vector2:
	# Find a position outside the camera's view
	var viewport_rect = get_viewport().get_visible_rect()
	var spawn_margin = 100.0 # Distance outside the screen edge

	var spawn_pos = Vector2.ZERO
	var edge = randi() % 4 # 0=top, 1=bottom, 2=left, 3=right

	match edge:
		0: # Top
			spawn_pos.x = randf_range(viewport_rect.position.x - spawn_margin, viewport_rect.end.x + spawn_margin)
			spawn_pos.y = viewport_rect.position.y - spawn_margin
		1: # Bottom
			spawn_pos.x = randf_range(viewport_rect.position.x - spawn_margin, viewport_rect.end.x + spawn_margin)
			spawn_pos.y = viewport_rect.end.y + spawn_margin
		2: # Left
			spawn_pos.x = viewport_rect.position.x - spawn_margin
			spawn_pos.y = randf_range(viewport_rect.position.y - spawn_margin, viewport_rect.end.y + spawn_margin)
		3: # Right
			spawn_pos.x = viewport_rect.end.x + spawn_margin
			spawn_pos.y = randf_range(viewport_rect.position.y - spawn_margin, viewport_rect.end.y + spawn_margin)

	# Make sure position is relative to the MainGame node if player moves freely,
	# or use global position if camera follows player. Assuming global for now.
	# This needs adjustment based on your camera setup. If camera is centered on player,
	# spawn relative to player position + viewport extents.
	var player_pos = player.global_position if is_instance_valid(player) else Vector2.ZERO
	spawn_pos += player_pos # Simple offset if camera is centered

	return spawn_pos


func load_level(level_path: String):
	print("MainGame loading level:", level_path)
	# Remove previous level node if it exists
	if current_level_node and is_instance_valid(current_level_node):
		current_level_node.queue_free()
		current_level_node = null

	# Clear existing enemies, projectiles, orbs? (Optional, depends on desired transition)
	clear_level_entities()

	var level_scene = load(level_path)
	if level_scene:
		current_level_node = level_scene.instantiate()
		# Add level behind player/enemies/etc. Use z-index or node order.
		add_child(current_level_node)
		move_child(current_level_node, 0) # Move to back

		# Reset spawner or load level-specific config
		current_spawn_interval = initial_spawn_interval # Reset timer interval
		enemy_spawn_timer.wait_time = current_spawn_interval
		# TODO: Load level-specific enemy lists `basic_enemy_scenes`, elite chances, boss triggers etc.
		# Example: if current_level_node.has_method("get_enemy_list"): basic_enemy_scenes = current_level_node.get_enemy_list()

		GameManager.load_level(level_path) # Notify GameManager
		print("Level loaded:", level_path)
	else:
		printerr("Failed to load level scene:", level_path)


func clear_level_entities():
	for enemy in enemy_container.get_children():
		enemy.queue_free()
	for proj in projectile_container.get_children():
		proj.queue_free()
	for orb in orb_container.get_children():
		orb.queue_free()
	print("Cleared level entities")
